#ifndef CHAR_ARR_HEADER
#define CHAR_ARR_HEADER

// this header needs
#include <stdio.h>
#include "../CHAR.h"
#include "../../NUMBER/INT.h"
#include "../../NUMBER/FLOAT.h"

// https://onlinetools.com/utf8/convert-code-points-to-utf8
// functions for character arrays

// elemental function pointers 
// (they depend on the encoding selected, its default behaviour is in ASCII)
char_enc CHAR_ARR_ENC_STATE = CHAR_ENC_ASCII;
byte   (* chk_ch_int)         (umax ch)                          = check_ascii_int; // checking
byte   (* chk_enc_ch)         (void * src, umax ssize)           = check_enc_ascii;
umax   (* get_ch_int)         (void * src, umax ssize)           = get_ascii_int; // get/write
void * (* wrt_enc_ch)         (umax ch, void * dest, umax dsize) = write_enc_ascii;
byte   (* prt_ch_int)         (umax ch)                          = print_ascii_int; // printing
byte   (* prt_enc_ch)         (void * src, umax ssize)           = print_enc_ascii;
// checking (unicode related)
byte   (* chk_ch_as_unicd)(umax ch)                              = check_ascii_as_unicd;
bool   (* chk_unicd_as_ch)(umax ch)                              = check_unicd_as_ascii;
// getting (unicode related)
umax   (* get_ch_as_unicd)(umax ch)                              = get_ascii_as_unicd;
umax   (* get_unicd_as_ch)(umax ch)                              = get_unicd_as_ascii;

// invalid character integers
umax INV_ENC_INT = INV_ASCII_INT;
// encoding number related characters
umax ENC_INT_NUMBER_LENGTH = ASCII_INT_NUMBER_LENGTH;
umax * ENC_INT_NUMBER = ASCII_INT_NUMBER;
// comma and newline
umax ENC_INT_COMMA = ASCII_INT_COMMA;
umax ENC_INT_NEWLN = ASCII_INT_NEWLN;
// whitespace
umax ENC_INT_WHITESPACE_LENGTH = ASCII_INT_WHITESPACE_LENGTH;
umax * ENC_INT_WHITESPACE = ASCII_INT_WHITESPACE;

// function to initialize the function pointers from above
char_enc set_ch_arr_enc_state(char_enc type);
void print_ch_arr_enc_state(void);
// ^ this function is called each time 
// one of the functions from below is called

// for now there are some basic functions
// I will add more overtime if I need to do
// more operations on character arrays

// functions for chint/chenc arrays
umax check_chint_arr(umax * arr, umax arr_size, char_enc enc);
umax check_chenc_arr(void * arr, umax arr_size, char_enc enc);
umax get_chenc_arr_ch_length(void * arr, umax arr_size, char_enc enc);
umax print_chint_arr(umax * arr, umax arr_size, char_enc enc);
umax print_chenc_arr(void * arr, umax arr_size, char_enc enc);
umax print_chint_arr_as_unicd(umax * arr, umax arr_size, char_enc enc);
umax print_chenc_arr_as_unicd(void * arr, umax arr_size, char_enc enc);
void * find_chint_in_chenc_arr(void * arr, umax arr_size, char_enc enc, umax chint);
void * skip_chints_in_chenc_arr(void * arr, umax arr_size, char_enc enc, umax * skip, umax skip_size);
void * skip_chencs_whtsp(void * skip, umax skip_size, char_enc enc);
// chint/chenc conversion
umax get_chint_arr_to_chenc_arr_size(umax * chints, umax csize, char_enc enc);
umax get_chenc_arr_to_chint_arr_size(void * chencs, umax csize, char_enc enc);
void * conv_chint_arr_to_chenc_arr(umax * chints, umax csize, char_enc enc, void * dest, umax dsize);
umax * conv_chenc_arr_to_chint_arr(void * chencs, umax csize, char_enc enc, umax * dest, umax dsize);
void * insert_chints_in_chenc_arr(void * arr, umax asize, char_enc enc, 
                                  void * ins_pos, umax * chints, umax csize);
umax remove_chencs_in_chenc_arr(void * arr, umax asize, char_enc enc,
                                void * rm_pos, umax rm_size);

// get primitive data types from a chenc array
umax check_chenc_arr_as_oct_int(void * arr, umax asize, char_enc enc);
umax get_chenc_arr_as_oct_int(void * src, umax ssize, char_enc enc);
umax check_chenc_arr_as_dec_int(void * arr, umax asize, char_enc enc);
umax get_chenc_arr_as_dec_int(void * src, umax ssize, char_enc enc);
umax check_chenc_arr_as_hex_int(void * arr, umax asize, char_enc enc);
umax get_chenc_arr_as_hex_int(void * src, umax ssize, char_enc enc);
// sign checking stuff
umax check_sign_mult(void * arr, umax asize, char_enc enc);
char get_sign_mult(void * src, umax ssize, char_enc enc);

// the actual functions to use
umax check_chenc_arr_as_uint(void * arr, umax asize, char_enc enc);
umax get_chenc_arr_as_uint(void * src, umax ssize, char_enc enc);
umax check_chenc_arr_as_sint(void * arr, umax asize, char_enc enc);
smax get_chenc_arr_as_sint(void * src, umax ssize, char_enc enc);
umax check_chenc_arr_as_float(void * arr, umax asize, char_enc enc);
fmax get_chenc_arr_as_float(void * src, umax ssize, char_enc enc);
umax check_chenc_arr_as_str(void * arr, umax asize, char_enc enc, umax end_chint);
void * get_chenc_arr_as_str(void * src, umax ssize, char_enc enc, umax end_chint);

// write primitive data types into a chenc array
void * write_octal_as_chenc_arr(umax number, void * arr, umax asize, char_enc enc);
void * write_dec_as_chenc_arr(umax number, void * arr, umax asize, char_enc enc);
void * write_hex_as_chenc_arr(umax number, void * arr, umax asize, char_enc enc);
void * write_uint_as_chenc_arr(umax number, void * arr, umax asize, char_enc enc);
void * write_sint_as_chenc_arr(smax number, void * arr, umax asize, char_enc enc);
void * write_float_as_chenc_arr(fmax number, void * arr, umax asize, char_enc enc);

#include "CHAR_ARR.c"

#endif // CHAR_ARR_HEADER
